/*
 * @ProjectName: 综合安防
 * @Copyright:   2018 HangZhou Hikvision System Technology Co., Ltd. All Right Reserved.
 * @address:     http://www.hikvision.com
 * @date:        2018年01月29日 14:21
 * @description: 本内容仅限于杭州海康威视系统技术公有限司内部使用，禁止转发.
 */
package com.capsule.chapter.validate;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.util.List;

/**
 * <p>
 *
 * </p>
 *
 * @author xiachaoyang
 * @version V1.0
 * @date 2018年09月13日 14:32
 * @modificationHistory=========================逻辑或功能性重大变更记录
 * @modify By: {修改人} 2018年09月13日
 * @modify reason: {方法名}:{原因}
 * ...
 */
public class Validator<T> {

    private Class<T> entity;

    public Validator() {
    }

    public void validate() {
        entity = (Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass())
                .getActualTypeArguments()[0];
        if (this.entity != null) {
            Field[] fields = entity.getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                //获取字段中包含Validation的注解
                Validation v = field.getAnnotation(Validation.class);
                if (v != null) {
                    if(!v.allowEmpty()){
                        validateEmpty(field);
                    }
                    if(v.allowRange().length == 2 && v.allowRange()[0] >= Integer.MIN_VALUE && v.allowRange()[1] <= Integer.MAX_VALUE){
                        validateRange(field,v);
                    }
                    if(v.maxLength() > 0){
                        validateMaxLength(field,v);
                    }
                }
            }
        }
    }

    private void validateMaxLength(Field field, Validation v) {
        try {
            Object val = field.get(this);
            boolean flag = true;
            if(val instanceof String){
                if(String.valueOf(val).length() > v.maxLength()){
                    flag = false;
                }
            }
            if(val instanceof List){
                if(((List) val).size() > v.maxLength()){
                    flag = false;
                }
            }
            if(!flag){
                throw new ApiException(2,String.format("Param \"%s\" is exceed max length[%d]!",field.getName(),v.maxLength()));
            }
        }catch (IllegalAccessException e) {
            throw new ApiException(-1,"UNSUPORT");
        }
    }

    private void validateRange(Field field, Validation v) {
        try {
            Object val = field.get(this);
            boolean flag = true;
            if(val instanceof Integer || NumberUtils.isDigits(val+"")){
                Integer value = (Integer) val;
                if(val == null || v.allowRange()[0] > value || v.allowRange()[1] < value || v.allowRange()[0] > v.allowRange()[1]){
                    flag = false;
                }
            }
            if(val instanceof List){
                if(val == null || ((List)val).size() == 0){
                    flag = false;
                }
            }
            if(!flag){
                throw new ApiException(2,String.format("Param \"%s\" is out of range or illegal range configuration [%d,%d]!",field.getName(),v.allowRange()[0],v.allowRange()[1]));
            }
        }catch (IllegalAccessException e) {
            throw new ApiException(-1,"UNSUPORT");
        }
    }

    /**
     * 校验字符串、集合是否为空
     * @param field
     */
    private void validateEmpty(Field field) {
        try {
            Object val = field.get(this);
            if(val instanceof String){
                if(StringUtils.isEmpty(String.valueOf(val))){
                    throw new ApiException(1,String.format("Param \"%s\" is blank,but required!",field.getName()));
                }
            }
        } catch (IllegalAccessException e) {
           throw new ApiException(-1,"UNSUPORT");
        }
    }
}
